package HTTPSendIntegrator;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public abstract class HTTPMmsMessage {

	protected static final String NL = "\r\n";

	public static final String MMS_STORE_STATUS_VALUE = "X-Mms-Store-Status";
	private String mmsStoreStatusValue;
	
	public static final String MMS_REPRT_ALLOWED = "X-Mms-Report-Allowed:";
	private String mmsReportAllowed;

	public static final String MMS_CONTENT_LOCATION_VALUE = "X-Mms-Content-Location:";
	private String mmsContentLocationValue;

	public static final String MMS_STATUS = "X-Mms-Status:";
	private String mmsStatus;

	public static final String MMS_READ_REPORT = "X-Mms-Read-Report:";
	private String mmsReadReport;

	/*
	 * =========================================================================
	 * Header Name Constants
	 * =========================================================================
	 */
	public static final String MMS_MESSAGE_TYPE = "X-Mms-Message-Type:";
	public static final String MMS_TRANSACTION_ID = "X-Mms-Transaction-ID:";
	public static final String MMS_VERSION = "X-Mms-MMS-Version:";
	public static final String MMS_DATE = "Date:";
	public static final String MMS_FROM = "From:";
	public static final String MMS_TO = "To:";
	public static final String MMS_CC = "CC:";
	public static final String MMS_BCC = "BCC:";
	public static final String MMS_SUBJECT = "Subject:";
	public static final String MMS_CLASS = "X-Mms-Message-Class:";
	public static final String MMS_EXPIRY = "X-Mms-Expiry:";
	public static final String MMS_DELIVERY_TIME = "X-Mms-Delivery-Time:";
	public static final String MMS_DELIVERY_REPORT = "X-Mms-Delivery-Report:";
	public static final String MMS_READ_REPLY = "X-Mms-Read-Reply:";
	public static final String MMS_STORE = "X-Mms-Store:";

	public static final String MMS_CONTENT_TYPE = "Content-Type:";
	public static final String MMS_RESPONSE_STATUS = "X-Mms-Response-Status:";
	public static final String MMS_RESPONSE_TEXT = "X-Mms-Response-Text:";
	public static final String MMS_MESSAGE_ID = "Message-ID:";
	public static final String MMS_RETRIEVE_STATUS = "X-Mms-Retrieve-Status:";

	/*
	 * =========================================================================
	 * Header Value Constants
	 * =========================================================================
	 */
	public static final String CHARSET_US_ASCII = "us-ascii";
	public static final String CHARSET_UTF8 = "utf-8";

	public static final String MMS_MESSAGE_TYPE_SEND_CONF = "m-send-conf";
	public static final String MMS_MESSAGE_TYPE_RETRIEVE_CONF = "m-retrieve-conf";
	public static final String MMS_MESSAGE_TYPE_FORWARD_CONF = "m-forward-conf";

	public static final String MMS_VERSION_1 = "1.0";

	public static final String MMS_DELIVERY_REPORT_YES = "Yes";
	public static final String MMS_DELIVERY_REPORT_NO = "No";

	public static final String MMS_CLASS_PERSONAL = "Personal";
	public static final String MMS_CLASS_ADVERTISEMENT = "Advertisement";
	public static final String MMS_CLASS_INFORMATIONAL = "Informational";
	public static final String MMS_CLASS_AUTO = "Auto";

	public static final String MMS_READ_REPLY_YES = "Yes";
	public static final String MMS_READ_REPLY_NO = "No";

	public static final String MMS_STORE_YES = "Yes";
	public static final String MMS_STORE_NO = "No";

	public static final String MMS_RESPONSE_STATUS_OK = "OK";
	public static final String MMS_RESPONSE_STATUS_ERROR_UNSPECIFIED = "Error-unspecified";
	public static final String MMS_RESPONSE_STATUS_ERROR_SERVICE_DENIED = "Error-service-denied";
	public static final String MMS_RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT = "Error-message-format-corrupt";
	public static final String MMS_RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = "Error-sending-address-unresolved";
	public static final String MMS_RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND = "Error-message-not-found";
	public static final String MMS_RESPONSE_STATUS_ERROR_NETWORK_PROBLEM = "Error-network-problem";
	public static final String MMS_RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = "Error-contant-not-accepted";
	public static final String MMS_RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE = "Error-unsupported-message";

	public static final String MMS_SENDER_VISIBILITY_HIDE = "Hide";
	public static final String MMS_SENDER_VISIBILITY_SHOW = "Show";

	public static final String MMS_ADDRESS_TYPE_MOBILE_NUMBER = "/TYPE=PLMN";
	public static final String MMS_ADDRESS_TYPE_MAIL = "";
	public static final String MMS_ADDRESS_TYPE_IPV4 = "/TYPE=IPV4";

	/*
	 * =========================================================================
	 * CONTENT TYPE CONSTANTS
	 * =========================================================================
	 */
	public static final String CTYPE_UNKNOWN = "*/*";
	public static final String CTYPE_TEXT = "text/*";
	public static final String CTYPE_TEXT_PLAIN = "text/plain";
	public static final String CTYPE_TEXT_HTML = "text/html";
	public static final String CTYPE_IMAGE = "image/*";
	public static final String CTYPE_IMAGE_JPEG = "image/jpeg";
	public static final String CTYPE_IMAGE_GIF = "image/gif";
	public static final String CTYPE_IMAGE_PNG = "image/png";
	public static final String CTYPE_MULTIPART = "multipart/*";
	public static final String CTYPE_MULTIPART_MIXED = "multipart/mixed";
	public static final String CTYPE_APPLICATION_MULTIPART_MIXED = "application/vnd.wap.multipart.mixed";
	public static final String CTYPE_APPLICATION_MULTIPART_RELATED = "application/vnd.wap.multipart.related";

	/*
	 * =========================================================================
	 * CLASS VARIABLES
	 * =========================================================================
	 */
	protected String mmsMessageType;
	protected String mmsTransactionId;
	protected String mmsVersion;
	private String mmsDate;
	private String mmsFrom;
	protected ArrayList<String> mmsTo;
	protected ArrayList<String> mmsCC;
	protected ArrayList<String> mmsBCC;
	private String mmsSubject;
	private String mmsClass;

	private String mmsExpiryTime;
	private String mmsDeliveryTime;

	private Boolean mmsDeliveryReport;
	private Boolean mmsReadReply;
	private Boolean mmsStore;

	private String mmsContentType;
	private String mmsResponseStatus;
	private String mmsResponseText;	
	private String mmsMessageID;					 //M-Retrive.conf
	private String mmsRetrieveStatus;  //M-Retrive.conf

	protected ArrayList<MmsPart> mmsParts;

	/*
	 * =========================================================================
	 * CONSTRUCTORS
	 * =========================================================================
	 */
	
	/** Creates an MmsMessage object. */
	public HTTPMmsMessage() {
		this.mmsTo = new ArrayList<String>();
		this.mmsCC = new ArrayList<String>();
		this.mmsBCC = new ArrayList<String>();
		this.mmsParts = new ArrayList<MmsPart>();
	}
	
	/*
	 * =========================================================================
	 * METHODS
	 * =========================================================================
	 */
	public boolean isExistFile()
	{ 
		return true;
	}
	
	public void setRetrieveStatus(String mmsRetrieveStatus){
		this.mmsRetrieveStatus= mmsRetrieveStatus;
	}
	public boolean isRetrieveStatus() {
		return mmsRetrieveStatus != null;
	}
	public String getRetrieveStatus() {
		return this.mmsRetrieveStatus;
	}
	
	public void setStoreStatusValue(String mmsStoreStatusValue){
		this.mmsStoreStatusValue = mmsStoreStatusValue;
	}
	public boolean isStoreStatusValue() {
		return mmsStoreStatusValue != null;
	}
	public String getStoreStatusValue() {
		return this.mmsStoreStatusValue;
	}
	
	public void setContentLocationValue(String mmsContentLocationValue){
		this.mmsContentLocationValue = mmsContentLocationValue;
	}
	public boolean isContentLocationValue() {
		return mmsContentLocationValue != null;
	}
	public String getContentLocationValue() {
		return this.mmsContentLocationValue;
	}

	public void setMessageType(String type) throws MmsMessageException {
		if (type.equals(MMS_MESSAGE_TYPE_RETRIEVE_CONF))
			this.mmsMessageType = type;
		else if (type.equals(MMS_MESSAGE_TYPE_SEND_CONF))
			this.mmsMessageType = type;
		else if (type.equals(MMS_MESSAGE_TYPE_FORWARD_CONF))
			this.mmsMessageType = type;
		else
			throw new MmsMessageException("Message type \"" + type	+ "\" not supported.");
	}

	/** Checks if the message type is specified. */
	public boolean isMessageTypeSet() {
		return mmsMessageType != null;
	}

	/** Sets the transaction id. */
	public void setTransactionID(String id) {
		this.mmsTransactionId = id;
	}

	/** Checks if the transaction identifier is set */
	public boolean isTransactionIDSet() {
		return mmsTransactionId != null;
	}

	/** Sets the version of the MMS message.<br> */
	public void setVersion(String version) throws MmsMessageException {
		if (version.equals(MMS_VERSION_1))
			this.mmsVersion = version;
		else
			throw new MmsMessageException("Message version \"" + version
					+ "\" not supported.");
	}

	/** Checks if the version is present. */
	public boolean isVersionSet() {
		return mmsVersion != null;
	}

	/** Sets the message date. */
	public void setMessageDate(String d) {
		this.mmsDate = d;
	}

	/** Sets the message date. */
	/*public void setMessageDate(long d) {
		this.mmsDate = d;
	}*/

	public boolean isMessageDateSet() {
		return mmsDate != null;
	}

	public void setMessageSender(String sender, String addressType)
			throws MmsMessageException {
		if (!addressType.equals(MMS_ADDRESS_TYPE_IPV4)
				&& !addressType.equals(MMS_ADDRESS_TYPE_MAIL)
				&& !addressType.equals(MMS_ADDRESS_TYPE_MOBILE_NUMBER))
			throw new MmsMessageException("Address type \"" + addressType
					+ "\" not supported.");
		this.mmsFrom = sender + addressType;
	}

	/** Checks if the message sender is specified. */
	public boolean isMessageSenderSet() {
		return mmsFrom != null;
	}

	/** Adds a message receiver. */
	public void addMessageReceiver(String receiver, String addressType)
			throws MmsMessageException {
		if (!addressType.equals(MMS_ADDRESS_TYPE_IPV4)
				&& !addressType.equals(MMS_ADDRESS_TYPE_MAIL)
				&& !addressType.equals(MMS_ADDRESS_TYPE_MOBILE_NUMBER))
			throw new MmsMessageException("Address type \"" + addressType
					+ "\" not supported.");
		this.mmsTo.add(receiver + addressType);
	}

	public boolean isMessageReceiverSet() {
		return mmsTo.size() > 0;
	}

	public List<String> getMessageReceivers() {
		return mmsTo;
	}

	public void addMessageCC(String receiver, String addressType)
			throws MmsMessageException {
		if (!addressType.equals(MMS_ADDRESS_TYPE_IPV4)
				&& !addressType.equals(MMS_ADDRESS_TYPE_MAIL)
				&& !addressType.equals(MMS_ADDRESS_TYPE_MOBILE_NUMBER))
			throw new MmsMessageException("Address type \"" + addressType
					+ "\" not supported.");
		this.mmsCC.add(receiver + addressType);
	}

	public boolean isMessageCCSet() {
		return mmsCC.size() > 0;
	}

	public List<String> getMessageCC() {
		return mmsCC;
	}

	public void addMessaceBCC(String receiver, String addressType)
			throws MmsMessageException {
		if (!addressType.equals(MMS_ADDRESS_TYPE_IPV4)
				&& !addressType.equals(MMS_ADDRESS_TYPE_MAIL) && !addressType.equals(MMS_ADDRESS_TYPE_MOBILE_NUMBER))
			throw new MmsMessageException("Address type \"" + addressType
					+ "\" not supported.");
		this.mmsBCC.add(receiver + addressType);
	}

	public boolean isMessageBCCSet() {
		return mmsBCC.size() > 0;
	}

	public List<String> getMessageBCC() {
		return mmsBCC;
	}

	public void setMessageSubject(String subject) {
		this.mmsSubject = subject;
	}

	public boolean isMessageSubjectSet() {
		return mmsSubject != null;
	}

	public void setMessageClass(String messageClass) throws MmsMessageException {
		if (!messageClass.equals(MMS_CLASS_AUTO)
				&& !messageClass.equals(MMS_CLASS_PERSONAL)
				&& !messageClass.equals(MMS_CLASS_INFORMATIONAL)
				&& !messageClass.equals(MMS_CLASS_ADVERTISEMENT))
			throw new MmsMessageException("Message class \"" + messageClass
					+ "\" not supported");
		this.mmsClass = messageClass;
	}

	public boolean isMessageClassSet() {
		return mmsClass != null;
	}
	
	public void setMessageExpiryTime(String time) {
		this.mmsExpiryTime = time;
	}

	public boolean isMessageExpiryTimeSet() {
		return mmsExpiryTime != null;
	}

	public void setMessageDeliveryTime(String time) {
		this.mmsDeliveryTime = time;
	}

	public boolean isMessageDeliveryTimeSet() {
		return mmsDeliveryTime != null;
	}
	public void setDeliveryReport(boolean enabled) {
		this.mmsDeliveryReport = new Boolean(enabled);
	}

	public void setReadReply(boolean enabled) {
		this.mmsReadReply = new Boolean(enabled);
	}

	public void setStore(boolean enabled) {
		this.mmsStore = new Boolean(enabled);
	}

	public void setResponseStatus(String status) throws MmsMessageException {
		if (!status.equals(MMS_RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED)
				&& !status
						.equals(MMS_RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT)
				&& !status.equals(MMS_RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND)
				&& !status.equals(MMS_RESPONSE_STATUS_ERROR_NETWORK_PROBLEM)
				&& !status
						.equals(MMS_RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED)
				&& !status.equals(MMS_RESPONSE_STATUS_ERROR_SERVICE_DENIED)
				&& !status.equals(MMS_RESPONSE_STATUS_ERROR_UNSPECIFIED)
				&& !status
						.equals(MMS_RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE)
				&& !status.equals(MMS_RESPONSE_STATUS_OK))
			throw new MmsMessageException("Status \"" + status
					+ "\" not supported");
		this.mmsResponseStatus = status;
	}

	/**
	 * Checks if the response status is present.
	 * 
	 * @return true if present
	 */
	public boolean isResponseStatusSet() {
		return mmsResponseStatus != null;
	}

	/**
	 * Sets the response text.
	 * 
	 * @param text
	 *            response
	 */
	public void setResponseText(String text) {
		this.mmsResponseText = text;
	}

	/**
	 * Checks if the response text is present.
	 * 
	 * @return true if present
	 */
	public boolean isResonseTextSet() {
		return mmsResponseText != null;
	}

	public boolean isDeliveryReportSet() {
		return this.mmsDeliveryReport != null;
	}

	public boolean isReadReplySet() {
		return this.mmsReadReply != null;
	}

	/**
	 * Sets the message identifier.
	 * 
	 * @param id
	 *            message identifier
	 */
	public void setMessageID(String id) {
		this.mmsMessageID = id;
	}

	/**
	 * Checks if the message identifier is present.
	 * 
	 * @return true if present
	 */
	public boolean isMessageIDSet() {
		System.out.println("mmsMessageID:"+mmsMessageID);
		return mmsMessageID != null;
	}

	/**
	 * Sets the content type for the message.<br>
	 * 
	 * Supported content types:
	 * <ol>
	 * <li>{@link #CTYPE_APPLICATION_MULTIPART_MIXED}</li>
	 * <li>{@link #CTYPE_APPLICATION_MULTIPART_RELATED}</li>
	 * <li>{@link #CTYPE_IMAGE}</li>
	 * <li>{@link #CTYPE_IMAGE_GIF}</li>
	 * <li>{@link #CTYPE_IMAGE_JPEG}</li>
	 * <li>{@link #CTYPE_IMAGE_PNG}</li>
	 * <li>{@link #CTYPE_MULTIPART}</li>
	 * <li>{@link #CTYPE_MULTIPART_MIXED}</li>
	 * <li>{@link #CTYPE_TEXT}</li>
	 * <li>{@link #CTYPE_TEXT_HTML}</li>
	 * <li>{@link #CTYPE_TEXT_PLAIN}</li>
	 * <li>{@link #CTYPE_TEXT_WML}</li>
	 * <li>{@link #CTYPE_UNKNOWN}</li>
	 * </ol>
	 */
	public void setMessageContentType(String type) {
		this.mmsContentType = type;
	}

	public boolean isMessageContentTypeSet() {
		return mmsContentType != null;
	}

	public void addPart(MmsPart part) throws MmsMessageException {
		if (mmsContentType.equals(CTYPE_MULTIPART)
				|| mmsContentType.equals(CTYPE_MULTIPART_MIXED)
				|| mmsContentType.equals(CTYPE_APPLICATION_MULTIPART_MIXED)
				||
				// Multipart related not yet supported
				mmsContentType.equals(CTYPE_APPLICATION_MULTIPART_RELATED)
				|| mmsContentType.equals(CTYPE_UNKNOWN))
			mmsParts.add(part);
		else if (mmsParts.size() == 0)
			mmsParts.add(part);
		else
			throw new MmsMessageException(
					"Only one part admitted in a non Multipart message");
	}

	/**
	 * Return the number of parts in the message.
	 * 
	 * @return parts number
	 */
	public int getPartsNumber() {
		return mmsParts.size();
	}

	public List<MmsPart> getParts() {
		return mmsParts;
	}

	public MmsPart getPart(int i) {
		try {
			return mmsParts.get(i);
		} catch (IndexOutOfBoundsException e) {
			return null;
		}
	}

	public String getMessageType() {
		return this.mmsMessageType;
	}

	/**
	 * Returns the transaction id.
	 * 
	 * @return transaction id
	 */
	public String getTransactionID() {
		return this.mmsTransactionId;
	}

	/**
	 * Return the version of the MMS Protocol.
	 * 
	 * @return version of MMS
	 */
	public String getVersion() {
		return this.mmsVersion;
	}

	/**
	 * Returns the date of the message.
	 * 
	 * @return message's date
	 */
	public String getMessageDate() {
		return this.mmsDate;
	}

	/**
	 * Return the message sender.
	 * 
	 * @return sender
	 */
	public String getMessageSender() {
		return this.mmsFrom;
	}

	/**
	 * Return the message subject.
	 * 
	 * @return message subject
	 */
	public String getMessageSubject() {
		return this.mmsSubject;
	}

	/**
	 * Returns the message class.
	 * 
	 * @return message class
	 */
	public String getMessageClass() {
		return this.mmsClass;
	}

	/**
	 * Returns the message expiry time.
	 * 
	 * @return expiry time
	 */
	public String getMessageExpiryTime() {
		return this.mmsExpiryTime;
	}

	/**
	 * Returns the delivery time of the message.
	 * 
	 * @return delivery time
	 */
	public String getMessageDeliveryTime() {
		return this.mmsDeliveryTime;
	}

	/**
	 * Checks whether the delivery report is enabled
	 * 
	 * @return true if enabled
	 */
	public boolean isDeliveryReportEnabled() {
		return this.mmsDeliveryReport;
	}

	/**
	 * Checks whether the read reply is enabled
	 * 
	 * @return true if enabled
	 */
	public boolean isReadReplyEnabled() {
		return this.mmsReadReply;
	}

	public boolean isStoreEnabled() {
		return this.mmsStore;
	}

	/**
	 * Returns the response status.
	 * 
	 * @return response status
	 */
	public String getResponseStatus() {
		return this.mmsResponseStatus;
	}

	/**
	 * Returns the response text
	 * 
	 * @return response text
	 */
	public String getResponseText() {
		return this.mmsResponseText;
	}

	/**
	 * Returns the message identifier
	 * 
	 * @return message identifier
	 */
	public String getMessageID() {
		return this.mmsMessageID;
	}

	/**
	 * Returns the message content type.
	 * 
	 * @return message content type
	 */
	public String getMessageContentType() {
		return this.mmsContentType;
	}

	/**
	 * Produce a string representation of the message easily readable by a
	 * human.
	 * 
	 * @return string representation of the message
	 */
	public String toString() {
		String mmsMessage = "";
		return mmsMessage;
	}
}
